Preface

This is a list of frequently asked questions (FAQ) about porting programs to the MIPS ABI. A current copy of this FAQ is available by contacting SGI Developer Support devprogram@sgi.com or marketing@mipsabi.org (please put ABI FAQ in the Subject line to insure expeditious routing).

This is an evolutionary document, which will be most useful if feedback on its' contents is received. Suggestions, improvements, new questions (preferably *with* answers), and better answers are always welcome.

Introduction

This document is a set of notes on porting to the MIPS ABI. This information is not the standard. The standard is defined by the Conformance Guide (What is the Black Book?). (The Conformance Guide is also informally referred to as the Black Book). In case of a dispute, refer to the official standards documents. This document is intended to be a quick place to look things up, and does not in any way eliminate the need to read and understand the standard.

Much of the programming information has to do with porting from a BSD-flavor environment to an SVR4-flavor environment. Many popular systems, including IRIX 4 and SunOS, have some BSD flavor to them, but also have non-BSD aspects, so included examples may or may not be directly applicable. Other issues are POSIX support (for signals and other things), porting to ANSI C, and using IEEE math. There are much more complete works available regarding such code transitions. Again, this is only a collection of pointers, not an absolute reference.

Quick instructions

If you read nothing else in this faq, these instructions will still get you going:

General Information

What is the MIPS ABI? What is it for?

The MIPS ABI is an Application Binary Interface for MIPS processors running UNIX SVR4. It documents a standard binary interface for application programs on systems based on members of the MIPS processor family that implement the interfaces of UNIX System V Release 4.0 or above.

The MIPS ABI is actually comprised of a number of documents (What makes up the spec?).

The MIPS ABI Group has worked to complete the standard in order to allow software vendors to port their applications to the ABI and be confident that it will operate correctly on all the platforms that support the ABI.

What systems support the ABI?

The following vendors are shipping operating systems which support the MIPS ABI:

What is the Reference Platform model?

The MIPS ABI is based on a Reference Platform (RP model. Under this model, a single platform is designated as a "tie-breaker". The software developer should build and test the application on the RP; the other ABI-conforming vendors guarantee that ABI compliant binaries that run correctly on the RP will run correctly on their platforms.

To be strictly accurate, there are two different forms of ABI compliance. All the ABI-conforming systems are ABI Execution Platforms the Reference Platform is the "tie-breaker" for how a program should work. There are also ABI Generation Platforms which are used to build ABI programs; the Reference Platform is again the "tie-breaker". The ABI generation environment need not necessarily be hosted on top of an ABI execution environment. As of the current version of this document, only the Reference Platform is an approved Generation Platform, although there are plans to certify additional Generation Platforms in the near future.

Given the current situation, it is thus a requirement that a software developer have a Reference Platform on hand, or visit or remotely access a porting center, in order to perform and test an ABI port.

A cornerstone of this strategy is the availability of test technology to certify ABI compliance of a binary. At the moment, facilities for such testing are available, but limited in scope (How to check if it's ABI compliant). Improved application checking technology is under development and is expected to be available in the second half of 1995.

Which Reference Platform version should I use?

Each edition of the Conformance Guide has a matching Reference Platform which implements that level of technology. For version 1.1 of the Conformance Guide, the Reference Platform is Silicon Graphics IRIX 5.3 with the "IRIS Development Option" ("IDO") 3.19 and patches 183, 410, 448, 541, 595, 596, and 604. The IDO is essentially the compilers and libraries. Any Silicon Graphics system which can run this software can be a Reference Platform.

Prior to the release of IRIX 5.3, IRIX 5.2 with IDO 3.18 or IRIX 5.1 with IDO 3.17 plus a special ABI Construction Kit (available from the SGI Developer's Technical Program) was used as the Reference Platform for the 1.1 Conformance Guide). The Reference Platform conforming to the 1.0 Conformance Guide edition was MIPS Computer Systems' RISC/os 5.01 with ANSI C 3.11.

The Reference Platform for the (future) 1.2 Conformance Guide will be a future version of IRIX.

The ABI maintains backwards, but not forwards compatibility, so programs developed on the earlier RP will execute on the later ones, but will not be able to take advantage of new features.

In general, the latest RP is the best one to develop on, as it is likely to have the strongest level of support available.

What is the Black Book?

The Black Book is the MIPS Processor ABI Conformance Guide. It is the defining document for the ABI. The current version of the Black Book may be found in Version 1.1.2

What makes up the spec? Further reading

The ABI is defined by a series of documents. The basic defining document is SVID 3. The Generic ABI defines those elements which must be available on all ABI compliant platforms. The MIPS Processor Supplement defines how the Generic ABI is implemented on the MIPS processor family. The Conformance Guide defines additional interfaces agreed upon by the MIPS ABI group members, and provides guidance in implementation.

These are the references for the documents which define the standard:

Where to find documents, support, info

The Conformance Guide is available from participating vendors It is also available in PostScript form to registered developers in the SGI Developer Program, on the Developer Toolbox CD-ROM, release 4.0 and beyond.

The SGI Developer Toolbox also includes a note in PostScript format on porting to the ABI, and some sample programs illustrating porting techniques.

Which version of the ABI does a system support?

Prior to the 1.2 Conformance Guide, there is no reliable programmatic interface for determining which version of the ABI a particular system conforms to. Contact the system vendor for further information.

Specific features can usually be tested for, but compliance levels cannot be inferred from this, as the particular feature may have been introduced on a given platform before full compliance for the version of the spec in which the feature first appeared.

With the 1.2 Conformance Guide, the ABI version will be obtainable by examining the file /etc/mipsabiversion. If this file is not present, the only assumption that should be made is pre-1.2.

What is OCMP?

The Open Computing environment for MIPS Platforms ("OCMP") group is a Japanese version of a MIPS ABI. Several MIPS ABI group members are also active in OCMP. The OCMP-ABI is aligned with the 1.0 version of the Conformance Guide, with a number of extensions for internationalization and localization, CD-ROM access, X11R5 and OSF/Motif 1.2, to name a few. The MIPS ABI and OCMP groups work together to keep the specifications aligned, and in fact X11R5 and OSF/Motif 1.2 became part of the MIPS ABI specification with the 1.1 Conformance Guide. The OCMP web page may be found at http://www1.sony.co.jp

A port to the OCMP specification will allow an application to run in Japanese double-byte character mode on any OCMP compliant platform, and will still be MIPS ABI compliant.

OCMP members include:

Programming

Which preprocessor symbols should be used?

There is no simple answer to this question, and is best left to the internal coding conventions of each software developer.

Here are some possible guidelines:

For high-level standard definitions, there are some commonly used symbols which may be useful in porting. Such defines are used to select major functionality sets based on the heritage of the target operating system. For example, SVR4, SYSV, BSD43 and OSF1 are often used. The appropriate symbol for the MIPS ABI would be SVR4. This symbol is not automatically defined on the Reference Platform, and should be defined in the Makefile.

For standards such as ANSI C, POSIX, and X/Open, the appropriate symbols are __STDC__, _POSIX_SOURCE, _XOPEN_SOURCE. Appropriate defines and values for these are supplied by the compiler on the Reference Platform. The IRIX Reference Platform also introduces the private symbol _ABI_SOURCE, which is automatically defined when the abicc script is used for compilation. This symbol is used to select functionality from system header files.

Fine-grained feature tests can be used for specific features of interest. To illustrate the techniques, the missing index string routine can either be selected at an operating system functionality level:

	#ifdef SVR4
     #define index(s, c)     strchr((s), (c))
     #endif

Or at a feature level:

     #ifdef HAVE_STRCHR
     #define index(s, c)     strchr((s), (c))
     #endif

It may be useful to use the operating system-level define to select the feature-level define, as follows:

     #ifdef SVR4
     #define HAVE_STRCHR
     #endif
     
     ...
     
     #ifdef HAVE_STRCHR
     #define index(s, c)     strchr((s), (c))
     #endif

Where are the right include files?

On the IRIX Reference Platform, the includes files for ABI programming are simply in /usr/include, with the exception of the OSF/Motif include files, which are in /usr/include/abi. The proper sections of the standard include files are selected when _ABI_SOURCE is defined. The abi specific include files are selected when -abi is given to the compiler. Both are selected automatically when abicc is used (the preferred compilation method).

On the Reference Platform for the 1.0 Conformance Guide (RISC/os 5.01), the include files are those from the SVR4 environment, /svr4/usr/include. These are selected automatically when /svr4/bin/cc is used for compilation.

Where's the socket Code? rpc? xdr?

Many of the network functions and definitions that were present in the BSD libc are now in libsocket.so. Programs which use socket-based networking services will need to be linked with -lnsl -lsocket. The socket library is actually emulation code built on top of services provided by the network services library (libnsl) so it is not generally possible to specify just -lsocket.

Programs which use the X11 and Motif interfaces will need to link with these libraries.

The ABI requires that programs which use dynamic shared objects specify them on the link line so that they appear in the dependency list. Do not count on ABI libraries having built-in dependencies. These dependencies may differ on different platforms, so a program may work on one because the dependency is supplied "invisibly", then fail on others. Use elfdump -Dl on the IRIX Reference Platform to check the library list (ldd may be appropriate on some other platforms).

The socket emulation code does not always provide exactly equivalent functionality to native sockets. Routines such as gethostbyname may have different behavior; in particular, gethostbyname differs in that under socket emulation, it only returns information from the /etc/hosts file, it does not access NIS or the nameserver. Some platforms may provide a native socket interface, or may have modified the generic socket emulation library to provide additional functionality; the point is that applications can not count on more functionality than is provided by the generic socket eumlation library.

The rpc and xdr routines are in libnsl, and the old rpcsvc library is no longer present.

Global symbols in dlopen attachments

Objects loaded by a call to dlopen can, in general, not access objects loaded by a different call to dlopen. A provision for making symbols in a dlopen attached object global will be introduced with the 1.2 Conformance Guide, where the RTLD_GLOBAL flag can be or'd with the mode argument to dlopen. Until the RTLD_GLOBAL functionality is implemented, dlsym should be used to indirectly reference the symbols. For example, if routine sub2 in module mod2 wants to call routine sub1 in mod1, one (simple-minded) way to make that work would be as follows:

   dltest.c:
     void *dlhandle1, *dlhandle2;
     int (*sub1_ptr)(int);
     
     ...
     
         /* open objects */
         dlhandle1 = dlopen ("mod1.o", RTLD_NOW);
         dlhandle2 = dlopen ("mod2.o", RTLD_NOW);
     
         /* find address of function */
         if (*sub1_ptr == NULL)
             sub1_ptr = (int (*)())dlsym (dlhandle1, "sub1");
         (void) sub2 ();

   mod1.c:
     /* define routine sub1() */
     int sub1 (int arg);
     
     int
     sub1 (int arg)
     {
         printf ("This is a test of sub1 (arg %d)\n", arg);
         return 1;
     }

   mod2.c:
     /* call routine in different dlopen() attachment */
     #include <stdio.h>
     #define CALL_ARG 10
     extern int (*sub1_ptr)(int);
     
     void
     sub2()
     {
         int rv = 0;
     
         if (*sub1_ptr != NULL)
             rv = (*sub1_ptr)(CALL_ARG);
         else
             printf ("routine not mapped\n");
     }

When RTLD_GLOBAL is available, care should be taken not to overuse it. There are benefits to not having to worry about namespace conflicts, if symbols in DSOs in general are kept private, a DSO can be developed with fewer constraints, for example, when multiple groups are developing DSOs for a large product set and don't want to have to coordinate a "global namespace".

Another note about the above. The symbols contained in the original a.out and the objects loaded at program startup with the a.out are not available to dlsym, since they are directly available. If dlsym needs to access all the symbols in the aggregate symbol table, the ones from the a.out and objects loaded with the a.out at startup can be made available by making a call to dlopen with the PATHNAME argument set to 0.

Where's regex?

The regexp functions (see regexpr(3G)) are not defined in libc, as they are on some UNIX implementations. Under the MIPS ABI, you must link with libgen.a (-lgen) in order to get these definitions.

The libgen.a library is not specified by the ABI, but applications are free to link it in in their build. For questions about on-site linkage, see the section on Shipping Objects and Libraries

libgen.a will be included in version 1.2 of the Conformance Guide.

Where's nlist?

The nlist routine is in a library not specified by the ABI, and should be avoided. On IRIX and some other platforms it is found in libmld, on the rest it is found in libelf.

Using /proc Instead of ptrace.

Programs should use the /proc interface in preference to the ptrace routines to examine running programs. The ptrace routines are not standardized.

What is the mutual exclusion library?

A library for user-level mutual exclusion is provided in libmutex.so. Each vendor has implemented the functionality in the most optimal manner for the hardware, so providing the entry points as a DSO allows programs to access these routines in a portable manner. Programs should #include <abi_mutex.h> and add -lmutex to the load line to use this functionality. See the Conformance Guide for a definition of the interfaces.

What to use instead of bcopy, bzero, bcmp

The bcopy, bzero, and bcmp routines are available in the BSD Compatibility Library, however, the memory routines should be used instead. Note that bcopy can be replaced either by memcpy or memmove. memmove preserves the feature that overlapping copies work, and should be used if this is important.

     #ifdef SVR4
     #include <memory.h>
     #endif
     
     #ifdef  SVR4
     #ifndef bcmp
     #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
     #endif
     #ifndef bzero
     #define bzero(s, n)     memset ((s), 0, (n))
     #endif
     #ifndef bcopy
     #define bcopy(s, d, n)  memmove ((d), (s), (n))
     #endif
     #endif /* SVR4 */

What to use instead of index, rindex

The index and rindex routines are available in the BSD Compatibility Library, however, the strchr and strrchr routines should be used instead. Note that <string.h> should be included instead of <strings.h> even if the latter file exists on the system as it does, for example, on the current Reference Platform.

     #ifdef SVR4
     #include <string.h>
     #else
     #include <strings.h>
     #endif /* SVR4 */
     
     #ifdef  SVR4
     #ifndef index
     #define index(s, c)     strchr((s), (c))
     #endif
     #ifndef rindex
     #define rindex(s, c)    strrchr((s), (c))
     #endif
     #endif /* SVR4 */

Can I use strcasecmp?

The strcasecmp and strncasecmp routines, for doing case-insensitive string compares, is not part of the ABI. However, public-domain versions are available, or, since they are self-contained routines, the objects can be extracted from a static archive and included on the link line for the application.

What to use instead of getwd

The getwd routine is available in the BSD Compatibility Library, however, the standard routine getcwd is preferred. getcwd provides more functionality, so conversion is fairly straightforward. The following is one approach:

     #ifdef SVR4
     #include >sys/param.h>  /* for MAXPATHLEN */
     #define HAVE_GETCWD
     #endif
     
         ...
     
         char *string;
         char *cp;
     
     #ifdef HAVE_GETCWD
         cp = getcwd (string, MAXPATHLEN + 2);
     #else /* HAVE_GETCWD */
         cp = getwd (string);
     #endif /* HAVE_GETCWD */

What to use instead of getdtablesize

The getdtablesize routine is available in the BSD Compatibility Library, however, the use of the POSIX interface sysconf is preferred.

     #ifdef SVR4
     #include <sys/unistd.h>
     #endif /* SVR4 */
     
         ...
     
         long tsize;
     
     #ifdef _SC_OPEN_MAX
         tsize = sysconf (_SC_OPEN_MAX);
     #else  /* Assume BSD */
         tsize = getdtablesize();
     #endif

How to use setjmp And longjmp

The setjmp and longjmp routines are provided. However, the 4.3BSD setjmp and longjmp routines save and restore the signal mask, while the SVR4/MIPS ABI ones do not. If the 4.3BSD behavior is needed, the POSIX interfaces sigsetjmp and siglongjmp should be used. sigsetjmp and siglongjmp take a second argument, savemask, which, if non-zero, saves and restores the signal mask and scheduling parameters.

     #ifdef SVR4
     #define HAVE_SIGSETJMP
     #endif
     
     #ifdef HAVE_SIGSETJMP
     sigjmp_buf env;
     int savemask;
     #else
     jmp_buf env;
     endif
     
     ...
     
     #ifdef  HAVE_SIGSETJMP
         savemask = 1;
         sigsetjmp(env, savemask);
     #else
         setjmp(env);
     #endif /* HAVE_SIGSETJMP */

What to use instead of gethostname

The gethostname routine can be replaced by the use of the sysinfo routine.

     #ifdef SVR4
     #include <sys/systeminfo.h>
     #endif /* SVR4 */
     
         ...
     
         char buf[MAXHOSTNAME];
     
     #ifdef SVR4
         if (sysinfo(SI_HOSTNAME, buf, sizeof(buf)) < 0) {
             perror("SI_HOSTNAME");
             exit(BAD);
         }
     #else /* Assume BSD */
         if (gethostname(buf, sizeof(buf)) < 0) {
             perror("gethostname");
             exit(BAD);
         }
     #endif /* SVR4 */

What to use instead of gethostid

The MIPS ABI provides a function of the sysinfo routine for obtaining the host id. This should be used in preference to the gethostid call in the BSD compatibility library. Notice that sysinfo returns an ASCII representation of the value instead of a numeric one; this example uses strtoul to convert it to integer. See the Conformance Guide for details of sysinfo.

     #ifdef _ABI_SOURCE
     #include <limits.h>    /* for SYS_NMLN define */
     #include <sys/systeminfo.h>
     #endif
     
     ...
     
         int hostid
     #ifdef _ABI_SOURCE
         char hostbuf[SYS_NMLN]
         char *hp;
     #endif
     
     #ifdef _ABI_SOURCE
         sysinfo (_MIPS_SI_HOSTID, hostbuf, SYS_NMLN - 1);
         hostid = strtoul (hostbuf, (char **)NULL, 0);
     #else
         hostid = gethostid ();
     #endif

What to use instead of getpagesize

The POSIX sysconf routine should be used to obtain the page size.

     #include <sys/unistd.h>
     
     ...
     
         int pagesize
     
     #ifdef _ABI_SOURCE
         pagesize = sysconf (_SC_PAGESIZE);
     #else
         pagesize = getpagesize();
     #endif

How to open a pseudo-tty

(answer under construction). The SVR4 pty routines grantpt, ptsname and unlockpt should be used.

Using termios routines

The stty/gtty routines are not supported. The termio routines do exist, but should be replaced by the POSIX termios routines. The termios routines provide simple routines to perform common operations, rather than having to directly use the ioctl(2) interface. For example, cfsetospeed to change the output baud rate, tcflush to flush output, and tcsetattr to set arbitrary values in the termios structure. See termios(2) for details.

Note also that the termio structure is not specified by the ABI, and termios should be used instead. As a consequence, the ioctl calls which access the termio routines, TCGETA, TCSETA, TCSETAW and TCSEAF are not supported by the ABI; the call TCGETS, TCSETS, TCSETSW and TCSESF access the termios structure and are the appropriate alternatives if the code can't be converted to use the POSIX termios routines.

Where are ltchars defined?

A common porting problem from BSD-flavor UNIX is what to do with the ltchars structure. The termios can provide an alternative.

     /*
      * If _ABI_SOURCE is defined, use the `termios' 
	  * structure and provided routines instead of the 
	  * `ltchars' struct
      */
     #ifdef _ABI_SOURCE
     #define SVR4
     #endif
     
     #include <stdio.h>
     #include <sys/types.h>
     #ifdef SVR4
     #include <sys/termios.h>
     #else
     #include <sys/ioctl.h>
     #endif
     
     #ifdef SVR4
     struct termios old_tty, new_tty;
     #else
     #ifdef TIOCSLTC
     struct ltchars old_chars, new_chars;
     #endif
     #endif
     
     ...
     
     #ifdef SVR4
         /*
          * save off ltchars settings,
          * and change some - SVR4 flavor
          */
         tcgetattr (fileno (stdin), &old_tty);
         new_tty = old_tty;
         if (old_tty.c_cc[VLNEXT] == CTRL('v'))
             new_tty.c_cc[VLNEXT] = -1;
         if (old_tty.c_cc[VRPRNT] == CTRL('r'))
             new_tty.c_cc[VRPRNT] = -1;
         tcsetattr (fileno (stdin), TCSAFLUSH, &new_tty);
     #else /* !SVR4 */
     #ifdef TIOCSLTC
         /*
          * save off ltchars settings,
          * and change some
          */
         (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars);
         new_chars = old_chars;
         if (old_chars.t_lnextc == ctl('v'))
             new_chars.t_lnextc = -1;
         if (old_chars.t_rprntc == ctl('r'))
             new_chars.t_rprntc = -1;
         (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
     #endif
     #endif
     
     ...
     
     /*
      * on program exit, restore old ltchars settings
      */
     void
     on_quit()
     {
     #ifdef SVR4
         tcsetattr (fileno (stdin), TCSAFLUSH, &old_tty);
     #else /* !SVR4 */
     #ifdef TIOCSLTC
         (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars);
     #endif
     #endif
     }

Do I need to use IEEE math?

IEEE math is selected since __STDC__ is defined. As a result math functions return IEEE bounds conditions. For example, many routines return HUGE_VAL instead of HUGE in IEEE math mode.

     /*
      * illustrate the use of IEEE math
      * test that strtod called with an overflow-causing positive string
      * returns +HUGE (+HUGE_VAL for IEEE) and sets errno to ERANGE
      */
     #include <stdlib.h>
     #include <math.h>
     #include <errno.h>
     
     void prt_error (char *);
     
     ...
     
         char *str2 = "+9e+999";
     
         errno = 0;
     #ifdef _ABI_SOURCE
         if (strtod (str2, (char **)NULL) != HUGE_VAL)
     	prt_error ("FAILED, did not return HUGE_VAL.");
     #else
         if (strtod (str2, (char **)NULL) != HUGE)
     	prt_error ("FAILED, did not return HUGE.");
     #endif
         if (errno != ERANGE)
     	prt_error ("FAILED, errno not set to ERANGE.");
     
     ...
     
     /* stub for example */
     void
     prt_error (char *arg)
     {
             /*ARGSUSED*/
     }

How to use signals

The POSIX signal interfaces (sigaction, sigpending, sigprocmask, sigsuspend and sigsetjmp) should be used in ABI conforming applications, although the simplified interface will work fine. The IRIX manpages have excellent detail on this issue; see, for example, sigaction(2) and follow the *SEE ALSO* pointers.

Waiting for children to exit

The POSIX wait interfaces (wait and waitpid) should be used in ABI conforming applications. The IRIX manpages have excellent detail on this issue; see, for example, wait(2), which includes code samples.

Timing programs, or HZ is undefined

System clock rate information should not be obtained by looking at the define HZ, which is generally undefined, and in any case, would not be portable to different machines. Instead, sysconf should be used to obtain the information. One possible way to code this would be:

     #ifdef SVR4
     #include <unistd.h>
     #endif
     
     ...
     
     #ifdef SVR4
     #define HZ sysconf(_SC_CLK_TCK)
     #endif

If the clock rate is to be accessed very often, it is better to read in into a global variable at startup and change code to access the variable, thus saving a system call for each access.

gettimeofday takes only one argument

As defined by the ABI, the gettimeofday routine takes only a single argument, as timezone information is obtained from the environment variable TZ instead.

     #include <sys/time.h>
     
     ...
     
         struct timeval tv;
     #ifndef SVR4
         struct timezone tz;
     #endif
     
         ...
     
     #ifdef SVR4
         gettimeofday(&tv);
     #else
         gettimeofday(&tv, &tz);
     #endif

Shadow password file

In secure installations the /etc/passwd file may not contain the user's actual password. Applications should not assume that the password in /etc/passwd is the user's actual password and should not use it for user authentication, nor should they assume the presence of a shadow password file /etc/shadow.

Dereferencing NULL pointers

Not all ABI systems behave the same when NULL pointers are dereferenced. On some platforms, the program will fail with a segmentation violation, on others a read access will succeed because a read-only page has been mapped at address zero. The psABI suggests that mapping a page of memory at address 0 using mmap be left up to the individual process, but does not specifically mandate that the system leave address 0 unmapped. Application programmers may need to be aware of this possible difference in behavior.

/etc/mtab or /etc/mnttab?

The /etc/mnttab file used by some versions of the mount command and others, is not by itself an ABI requirement, and application programs should not depend on its' existence or format. On IRIX, this file is called /etc/mtab, for example.

/etc/fstab or /etc/vfstab?

The /etc/vfstab file used by some versions of the mount command and others, is not by itself an ABI requirement, and application programs should not depend on its' existence or format. On IRIX, this file is called /etc/fstab, for example.

Multiply defined global symbols

Not all development environments on ABI systems behave the same with respect to multiply defined global symbols. On some platforms, the loader will emit a warning, on others a fatal error. This has implications for applications which will be on-site linked; in the presence of multiple defined global symbols, linking may fail on some platforms. Application source code should be modified such that each external data symbol is defined in exactly one place, done by omitting the extern keyword. All other references should use the extern keyword.

Using stat/fstat/lstat

The MIPS ABI uses an expanded format for device types, known as Extended Fundamental Types (EFT). Routines which obtain device information, such as stat (and lstat and fstat) internally have a different interface to these routines, so those entry points are not in the standard C library. In order to correctly use the stat family of routines, the <sys/stat.h> *must* be included.

Using mknod

The MIPS ABI uses an expanded format for device types, known as Extended Fundamental Types (EFT). Routines which obtain device information, such as mknod, internally have a different interface to these routines, so those entry points are not in the standard C library. In order to correctly use the mknod routine, the <sys/stat.h> must be included.

Building and Packaging

How do I make an ABI binary?

On the IRIX Reference Platform, a wrapper shell script is supplied to provide command-line options compatible with those for the Software Generation System (SGS) described in the SVID 3. This script is supported on all Conformance Guide 1.1 compliant platforms, providing a mechanism for delivering software systems which are used by the end-user to construct tailored applications. It is also the preferred method for constructing ABI applications on the RP. This script is called abicc.

Using abicc allows the specific compiler calling conventions to be hidden. The specific invocation for three different revisions of the Reference Platform are noted in the rest of this section. Each is different, and there is no guarantee that the methods will not continue to change. Thus, the compilation method for IRIX 5.3 is simply to set an equate in the Makefile:

     CC = abicc


What if I have to use ld directly?

On the IRIX Reference Platform, a wrapper shell script is supplied to provide command-line options compatible with those for the Software Generation System (SGS) described in the SVID 3. This script is supported on all Conformance Guide 1.1 compliant platforms, providing a mechanism for delivering software systems which are used by the end-user to construct tailored applications. It is also the preferred method for constructing ABI applications on the RP. This script is called abild.

Using abild allows the specific compiler calling conventions to be hidden. The specific invocation for three different revisions of the Reference Platform are noted in the rest of this section. Each is different, and there is no guarantee that the methods will not continue to change. Thus, the suggested compilation method is simply to set an equate in the Makefile:

     LD = abild


Integrating PIC assembly language

Assembler code that is to be compiled in with an ABI application must be Position-Independent Code (PIC). There are a number of considerations here; for example the register usage conventions of the ABI must be observed. If the file is assembled directly by as, the -KPIC option must be supplied in order to activate the PIC directives. It is suggested that assembly language be assembled by the use of the abicc script rather than calling as directly. The code itself must contain a directive to produce PIC code:

     .option    pic2

Note that the assembly language format is not standardized by the ABI, so much care must be taken with assembly language which is to be used for "on-site linking"; in fact, it may not be possible. Standardizing the assembly language interface is under consideration by the MIPS ABI Group as a future direction.

How to check if it's ABI compliant?

If the program links correctly using the proper compiler switches, there is a tool which can be used to check the dangling references in an executable and make sure there are none outside the ABI. This tool is called check_abi_compliance. It reports references that are outside the ABI, and also missing references that are required by the ABI.

The tool check_for_syscalls can be used to check that an executable makes no system calls directly. All system calls are to be made by ABI-specified DSOs.

On the IRIX Reference Platform, elfdump can be used to examine information about an ELF file. A combination of dump and ldd may provide similar functionality on other platforms.

More sophisticated application checkers are under development and will be available in the future.

Building and shipping DSOs

It is quite reasonable to deliver custom DSOs as part of an application. ABI programs must use always Position Independent Code for calls to DSOs, and the DSO library must follow PIC conventions at the call point. The IRIX RP compilers generate PIC by default; on the RP for the 1.0 Conformance Guide (RISC/os), the -KPIC and -G0 options were necessary.

On IRIX 5.3 and 5.2, abild should be used to make the DSO. It takes the -G flag to do this. On IRIX 5.1, the -shared flag is needed. Note that abicc is not able to make a DSO directly, the objects need to be built first, then abild called to link the DSO.

If DSOs are attached via dlopen, some care must be taken with the visibility of symbols.

To check a DSO to make sure it is ABI compliant, run check_abi_interface on it. It may be worthwhile to construct a list of entry points in the DSO and install it in /usr/lib/abi/data. In this way, the interfaces provided by the DSO can be checked to make sure that they don't accidentally pull in non-ABI interfaces from other libraries (for example, references to gethostname, which is not part of the ABI).

Shipping objects and libraries: On-site linking

If an application includes a construction kit which is used by the end-user to make a binary, there are a few issues to consider.

First, the compilation environments on the different systems come from different sources, so getting the right arguments and flags on each system can be pretty tricky, and in particular, may require testing on each platform to get them right, which is at odds with the Reference Platform concept. To alleviate this problem, all the system suppliers have agreed to provide "standard" compiler wrappers abicc and abild that interpret arguments and flags from the SVR4 SGS.

Another potential problem is that libraries and include files outside the ABI are not guaranteed to be identical on all systems. Problems from this can only be avoided by careful planning when executing the port, and a thorough understanding of what is supported by the ABI. When linking an executable on the Reference Platform it is permissible to link in code from static archives that are not explicitly specified by the ABI, as long as those routines do not themselves use non-abi facilities. This has the potential for problems for on-site linkage, since it may cause differences in behavior if those static archives are implemented differently on the target than on the Reference Platform. Programs which are fully linked on the RP, on the other hand, will be consistent since they'll always have the RP version. Thus, caution is advised when requiring non-ABI libraries for an on-site linking situation.

Note that when ABI compliant libraries and object files are linked on a target system, the ABI specification does not require that the resulting executable be ABI compliant. However, the resulting binary must run on the target system if all the pieces of the original application were ABI compliant and the application would have run if linked on the Reference Platform.

As specific examples, the Math library, libm.a, is guaranteed to be compatible on all the ABI platforms, and can safely be used for on-site linkage.

The curses library (libcurses) in IRIX 5.2 is known to depend on private interfaces in libc.so.1 and on incompatible structure layouts and should be avoided for all uses.

The BSD compatibility library (libucb) may be incompatible across versions and should be avoided for on-site linkage.

The Motif library is a supported ABI library, and the ABI platform vendors have pledged to "make it work", but application vendors should take care to not depend too heavily on specific features of any specific OSF minor release. The release notes for the application should document the version of Motif it was built against for reference purposes.

The X11 library libXt is required by Motif and is supported for on-site linking, as is libgen. Other X11 libraries (libXaw, libXmu and libXext are no explcitly supported but may work. No specific X server extensions are supported by the ABI.

Distribution and media formats

An ABI application may be packaged for delivery either using the SVR4 packaging tools (pkgmk, pkgtrans, etc.), or use their own packaging and installation tools. In the latter case, tools must be restricted to those defined in chapter 8 of the gABI and the Conformance Guide.

Nodes for standard devices are provided in /dev/abi. See Chapter 2 of the Conformance Guide for the device names.

Where to install programs and data

According the the gABI, an application collectively called PKG should install static package objects in /opt/PKG, package objects that change in normal operations (such as log files) in /var/opt/PKG, and machine-specific configuration files in /etc/opt/PKG. Only package objects that must reside in specific locations within the system file tree in order to function properly (e.g., special files in /dev) should be installed in those locations.

The Conformance Guide extends these requirements slightly for efficiency reasons (to keep search paths short); for example executable objects installed in /opt/PKG/bin may symbolically link files to /opt/bin. See the Conformance Guide for details.

ABI platforms are required to provide the directories /opt/bin, /opt/man, and /opt/include.

When constructing installation scripts or pkgmap files, be aware that the /opt subtree may well be symbolically linked to someplace else - any existing links should be preserved.

How to debug an ABI application

On the IRIX reference platform, the dbx debugger can be used for full symbolic debugging. The way in which debugging information is encoded in the binary is not fully standardized, however, so binaries built on IRIX are only guaranteed to be debuggable at the assembly-language level on the other ABI platforms.

Finding what DSOs a program needs

On the IRIX Reference Platform, check what DSOs an executable needs by doing

elfdump -Dl PROGRAM

On the Reference Platform for the 1.0 Conformance Guide (RISC/os), use odump instead of elfdump.

Technology Questions

Which version of X11 is supported?

Version 1.0 of the Conformance Guide specified X11R4. Version 1.1 of the Conformance Guide specifies X11R5. libX11.so is supplied as a DSO. The correct version matching X11R5 is libX11.so.2. The correct version matching X11R4 is libX11.so.1.

The X Toolkit, libXt, is supplied as a static archive. Existing test technology is not available to insure that each vendor's implementation of libXt as a DSO is functionally equivalent, thus linking is to be done with the libXt static archive on the Reference Platform.

How much of X11 is supported by the ABI?

The X Consortium standard represented by libX11 is fully supported. The X Toolkit (libXt) is also supported. Other "standard" X11 libraries, such as libXaw, libXmu, and libXext, may be present on the Reference Platform as static archives, but are not officially supported. Portions of the X11R5 sample implementation which represent X Consortium "works in progress" may work but are not guaranteed to be supported. PEX is not covered by the ABI.

Which version of OSF/Motif is supported?

Version 1.0 of the Conformance Guide calls for support for Motif 1.1. Version 1.1 of the Conformance Guide updates this to Motif 1.2. The question of staying compatible across official patches to these major releases, and still addressing critical bugs, has proven to be a thorny issue. At this time, Conformance Guide 1.1 compliant platforms are expected to run Motif 1.2.3 plus some known fixes. 1.0 compliant platforms run Motif 1.1.3.

How much of OSF/Motif is supported by the ABI?

The entire Motif 1.2 library (libXm) is supported. Other Motif libraries may be present on the Reference Platform as static archives, but are not guaranteed to be supported. The Resource Manager (libMrm and User Interface compiler (uil and libuil) are not supplied on the Reference Platform.

Does the ABI work on multiprocessor machines?

A number of the ABI platforms are multiprocessor, and *will* run ABI applications. Some information about the configuration of the machine (number of processors, for example) is available through the sysinfo facility, but multi-threading and synchronization primitives for an MP environment are not covered by the ABI, and thus cannot be utilized by compliant programs. This is a subject for ongoing work by the MIPS ABI group.

Does the ABI apply to secure UNIX?

Normal (non-trusted) apps will run without changes. If an application knows that the system is secure and acts on it, it will not be considered ABI compliant. However, this does not mean that the same application running at different levels of security is necessarily non-ABI compliant.

What graphics extensions are supported?

The MIPS ABI group is considering specifying OpenGL as an optional component of the ABI in a future version of the Conformance Guide. Where present, implementations will be binary compatible. OpenGL provides a portable, device independent 3D graphics implementation.

Additional X11 libraries will be considered for standardization. The ABI will continue to track X11 releases from the X Consortium as appropriate; a statement on X11R6 will be forthcoming.

Is asynchronous I/O supported?

Asynchronous I/O will be introduced as a required interface with version 1.2 of the Conformance Guide. The interface follows the async I/O sections from POSIX 1003.1b.

What if the Global Offset Table is too small?

The Global Offset Table (GOT) is limited to 16,384 external references. In some circumstances, this has proven to be too small. The MIPS ABI Group has agreed to a specification for an expanded GOT for the 1.2 Conformance Guide. An ABI conforming application can not use expanded GOT facilities, even if available on the Reference Platform, and still be compliant with the 1.1 version of the Conformance Guide.

Alternative solutions are to modify the application to use fewer global symbols, or if the application uses its' own static archives, to turn some of those into DSOs, since each DSO has its' own GOT. The elfdump program on the Reference Platform can provide insight into the current size of GOTs.

How can I take advantage newer processor instruction sets?

Machines supporting the MIPS ABI range in size from laptop computers to large datacenter machines, come in multiprocessor configurations, offer fault tolerance, real-time capabilities, etc. The MIPS processor family includes members from the R2000 up through forthcoming high-end processors with a wide performance range. In order to support this range, the current ABI is pegged to a common denominator, the MIPS I instruction set architecture. The MIPS ABI group is considering extensions to take advantage of newer processor architectures as a future direction. For most applications, use of the MIPS I instruction set does not provide a significant performance penalty.

Is there an ABI C++? FORTRAN? Other languages

The MIPS ABI group recognizes that there are significant bodies of applications code which are not written in C, but which still could benefit from binary compatibility. The group's intention is to continue work to define standard binary compatible interfaces for FORTRAN, C++, and other languages as demand warrants. Some efforts along these line are in progress in future versions of gABI. At the present time, only the C interfaces defined by the ABI are supported on all platforms.

Reference Platform Setup, Bugs

This section describes workarounds for areas of known incompatibility of the IRIX 5.2 Reference Platform with the MIPS ABI. This information is not available for earlier Reference Platforms (RISC/os or IRIX 5.1).

The current Reference Platform (IRIX 5.3) Problems and issues may be found at the end of this document.

Setting up the IRIX ABI environment

While IRIX 5.2 with IDO 3.18 serves as the Reference Platform, it is not, by default, installed as an ABI environment.

The eoe1.sw.svr4net package must be installed to get the ABI libsocket and libnsl libraries. If this package is not installed from the miniroot, the system must be rebooted to force the kernel to be rebuilt before the changes will take effect.

The dev.sw.abi and compiler_dev.sw.abi packages must be installed to get the ABI Development environment.

The eoe2.sw.oampkg package must be installed in order to access the ABI packaging utilities.

Device nodes not made in /dev/abi

According to the Conformance Guide, devices for supported installation media are found in /dev/abi. If one of the supported media devices (floppy, QIC-120 cartridge, 6250 bpi 9-track tape, or ISO 9660 CD-ROM) is present on the system, the corresponding node should be found in /dev/abi. These nodes are not made on IRIX 5.2. This has been corrected in the IRIX 5.3 Reference Platform.

One possible workaround is to special-case installation for IRIX, to check known device names for these media. More likely, it is best to prompt for the installation device, rather than checking for particular defaults, thus avoiding the question of whether an expected default node has been made or not.

Some installation directories in /opt not made

The Conformance Guide specifies that the special install directories /opt/bin, /opt/man, and /opt/include are provided for symlinking files from /opt/PKG/*, in order that each package installed doesn't have to have its' bin directory added to the $PATH, or man directory added to $MANPATH. /opt/include and /opt/man are not made on IRIX 5.2. This has been corrected in the IRIX 5.3 Reference Platform.

The workaround is for an install procedure to check for these directories, and make them if they are not present.

The -abi flag is not documented for cc or ld

The -abi flag for cc and ld is used to make ABI binaries on the IRIX Reference Platform. This flag is not documented in the cc and ld manpages.

Developers are urged to use the abicc and abild wrappers to build ABI binaries. These wrappers hide the details of how cc or ld should be called. If the exact invocation is needed, cc -abi -v will show how the compiler passes are called; this output should be saved for reference, and will show the combination of preprocessor defines, ANSI compliance modes, etc. that make up ABI mode.

Mount command does not take -F TYPE

According to the ABI, the mount command should take the -F TYPE flag and argument. On IRIX 5.2, mount -t TYPE must be used instead.

Note that in the case of mounting an CD-ROM device, the IRIX mediad program may automatically mount the CD-ROM on the mountpoint /CDROM, as long as the CD-ROM is in a format mediad recognizes, and mediad is running. This behavior is not necessarily expected on other ABI-conforming platforms.

Mount command does not take cdfs type

The mount command does not accept the cdfs type. On IRIX 5.2, this type is called iso9660. In IRIX 5.3, cdfs is also accepted.

The monitor routine and profiling unavailable

The monitor library routine, and the synonym _monitor, are not found in the ABI C library on IRIX 5.2. On IRIX, the routine has been moved to libprof.a, which is not present in the ABI Development Environment. The cc compiler will also look for this library if the profiling flag (-p) is supplied, and fail to find it, resulting in an error message.

Profiling should probably not be used in an ABI application. The IRIX static archive libprof.a cannot be used, as it pulls in a number of non-ABI symbols.

This has been corrected in IRIX 5.3.

libucb.a is not provided

The Conformance Guide specifies that libucb.a is available as a transition aid for popular BSD UNIX interfaces. This library is not available on IRIX. However, virtually all of the functionality is available within libc. A possible workaround is to perform this command before compiling:

     cd /usr/lib/abi
     ln -s libc.so libucb.a
This is not guaranteed to work correctly in all cases, but might serve as a transitional aid (libucb.a is only supposed to be a transitional aid anyway). Be sure to run check_abi_compliance on the resulting binary to insure no non-ABI interfaces were pulled in.

libucb.a is scheduled to be phased out in future versions of the MIPS ABI.

_lib_version not set

_lib_version is not set in binaries generated on the Reference Platform running IRIX 5.2. ABI programs require ANSI C semantics, so _lib_version should be set non-zero. This will be corrected in the next release.

Socket library needs to be replaced

The run-time ABI socket library (libsocket)) in IRIX 5.2 has some bugs. The workaround is to arrange things so that the native IRIX libc is used to provide the socket interfaces. To perform this workaround, first check that the IRIX package eoe1.sw.svr4net is installed. If not installed, go back and install it, since this is required for the ABI execution environment.

     cd /usr/lib
     ls -l libsocket.so
     mv libsocket.so libsocket.so.orig
     ln -s libc.so.1 libsocket.so
The ls -l step is to check that the workaround has not already been enabled; if libsocket.so is already a symbolic link to libc.so.1, there is no need to continue as the workaround has been enabled.

Do *not* make any changes in the compile-time ABI environment, /usr/lib/abi.

In the next release, this problem will be corrected in a way such that the interfaces found in libsocket will actually be resolved against the native IRIX libc.

Some ABI static archives are not ABI-clean

Three of the static archives supplied in the ABI build environment on the IRIX 5.2 Reference Platform are not fully ABI-clean. The three libraries are libXt.a, libXmu.a, and libmld.a. Workarounds are generally possible if the non-ABI symbols are pulled in to a program (this will not always happen).

If check_abi_compliance reports compliance problems with the symbol gethostname, it could have come from any of the three libraries. The workaround is to provide a stub gethostname routine.

The other problems reported are with bzero and getpagesize

In each case providing the stub in the program itself will force the symbol to be resolved to the local routine, not to the non-ABI-compliance routine in a system DSO.

uname call workaround

The uname routine is a source-level interface. The internal calling sequence has not been properly standardized with the 1.1 Conformance Guide (an oversight in the standard itself). If the file <sys/utsname.h> is included on the IRIX 5.2 Reference Platform, the call to uname will not be binary compatible. The workaround is to include a stub routine which will cause the proper internal call for binary compatibility.

     static int
     uname (struct utsname *_buf)
     {
         int ret;
     
         ret = nuname(_buf);
         return ret;
     }

This has been corrected in IRIX 5.3.

Terminal Interface Routines

The preferred method of accessing the terminal interface is to use the general terminal interface routines specified by POSIX. These routines are tcgetattr, tcsetattr, tcsendbreak, tcdrain, tcflush, tcflow, cfgetospeed, cfsetospeed, cfgetispeed, cfsetispeed, tcgetpgrp, tcsetpgrp, tcgetsid.

The termio structure is not specified by the ABI, the termios structure should be used instead. As a consequence, the ioctl calls which access the termio routines, TCGETA, TCSETA, TCSETAW and TCSETAF are not supported by the ABI; the calls TCGETS, TCSETS, TCSETSW and TCSETSF access the termios structure and are the appropriate alternatives if the code can't be converted to use the POSIX terminal interface routines.

The curses library (libcurses, which is the same as the libterminfo or libtermcap library) and header file use the termio structure. As a result, programs linked with the curses library are generally not binary-compatible. As a workaround, a modified version of libcurses.a and curses.h are available from the MIPS ABI Developer Support Program. These modifications have been incorporated into IRIX 5.3.

Please note that alternative terminal and cursor management packages are not immune from these considerations; if a third-party developed package is being used with an application it should be checked. The par command (on IRIX) and truss command (other platforms) can be used to observe whether invalid ioctl(TCGETA) family calls are being made. Note that one such call will legitimately be made by a program via the isatty call, and since the structure is never manipulated by that call, it is safe.

Undefined Symbols During On-Site Linking

If an effort to link-edit ABI-compliant objects on a machine other than the Reference Platform results in error messages indicating undefined symbols, and the symbols are known not to really be undefined, it is probably due to a problem in the IRIX compilation system. The IRIX compilation system maintains two separate tables of symbol information, one is the ELF symbol table required by the MIPS ABI, the other is the mdebug section, which is used by certain of the other tools in the IRIX compilation system. In this bug, routines which are declared static in a particular code module are erroneously entered into the ELF symbol table as undefined symbols. Those ABI platforms which use compilation systems of a similar heritage to the one used in IRIX will be able to handle this case, but certain others will not.

One workaround is to use the -znodefs linker option, which allows a binary to be linked even if there are undefineds. Since these are not really undefined symbols, there will be no unmatched reference to them, so this is safe. Unfortunately, the abicc script only passes some linker-specific options down to the linker, and one of the ones it doesn't pass is -znodefs. If the nodefs workaround is to be used with abicc, something will need to be added to the options line in the configuration file for the particular abicc. On IRIX the configuration file is /usr/lib/abi/sgicc.cfg; the name and location will differ on other ABI platforms (check the ABILIB variable near the top of abicc). See abicc Doesn't Pass Some Linker Flags , for one approach to making this modification. A negative consideration here is that this modification has to be made not only to the machine a developer is working on, but also to customer sites for those customers who will be doing on-site linking of the application.

Another workaround requires obtaining a different linker and using it as a post-processor to remove these erroneous references from the ELF symbol table. This other linker is available from the MIPS ABI Developer Support Program. It is called ld32. The example illustrates how an object would be created using this scheme:

     abicc -c $OPTIONS sample.c
     ld32 -abi -r -g sample.o -o sample.x
     mv sample.x sample.o

Relocatable Objects Not ABI-Compliant

In certain circumstances it is desirable to combine objects into a relocatable aggregate object file which will be shipped as part of a product. While a similar effect often can be achieved by using an archive library, there are cases where a relocatable object is appropriate. The IRIX 5.2 compilation system will not produce a fully ABI-compliant object when ld -r is used.

The workaround requires obtaining a different linker and using it as a post-processor to recreate the required ordering of symbol table entries. This linker should only be used after the regular linker has been used to combine the objects, as it will not, by itself, produce the mdebug information that the regular IRIX linker, and other linkers of the same heritage, require. This other linker is available from the MIPS ABI Developer Support Program. It is called ld32. The example illustrates how an object would be created using this scheme:

     abicc -c $OPTIONS sample1.c
     abicc -c $OPTIONS sample2.c
     abicc -c $OPTIONS sample3.c
     abild -r -o sample.o sample1.o sample2.o sample3.o
     ld32 -abi -r -g sample.o -o sample.x
     mv sample.x sample.o
Note that ld32 must still be considered an unsupported workaround at this point, although it has received considerable testing.

See also the section on Undefined Symbols During On-Site Linking

sigaltstack Incompatibility

There is a difference between various ABI platforms in how the sigaltstack routine is implemented. On IRIX and some other platforms, the stack pointer ss_sp in the sigstk structure must be manually adjusted to point to the top of the new stack after the stack has been allocated, since stacks in the MIPS architecture grow down. On other platforms, the adjustment is made internally so that when the handler is active on the alternate stack, the stack pointer is in the right place.

Changing the behavior to be consistent across platforms would have introduced too much risk of incompatibility with existing application code, so while a more permanent solution is explored, a workaround is offered.

To guarantee working on all the ABI platforms, a stack twice the size actually estimated to be required can be allocated. The stack pointer is then moved up by the original estimated size. This results in a stack pointer at the top of the space for automatically-adjusting systems, and in the middle, but still with as much space as the original estimate, on the non-adjusting systems.

A refinement on the above approach would be to use the *allocate double* method in a test case run at initialization time, force the signal handler for the test case to be invoked, and have it examine where the stack pointer is placed relative to the ss_sp field to determine whether this is an automatically-adjusting or a non-adjusting system. The information would be stored in a global variable for use by the remainder of the program.

Example code illustrating the allocate double scheme follows:

     #include <signal.h>
     
     ...
     
     /*
     * allocate alternate stack
     * MIPS ABI version: allocates extra space, adjusts
     * stack pointer compatibly for all platforms
     */
     int
     setup_altstack (stack_t *sigstk, stack_t *osigstk, int altstacksize, .... )
     {
         int altstackadj = altstacksize;
     
         /* set up alternate stack */
         if ((sigstk->ss_sp = (char *) malloc (altstacksize*2)) == NULL) {
     	    perror("malloc");
     	    return -1;
         }
         sigstk->ss_size = altstacksize;
     
         /* adjust ss_sp to point to middle of stack */
         sigstk->ss_sp += altstacksize - sizeof (int);
         sigstk->ss_flags = 0;
             if (sigaltstack(sigstk, osigstk) < 0) {
                     perror("sigaltstack");
                     return -1;
             }
     }

makecontext Incompatibility

The makecontext routine has the same problem as sigaltstack in that on some platforms, the stack pointer described by the ucontext structure uc_stack element is automatically adjusted when the registered signal handler is invoked, while on other platforms it is left unchanged as it is expected to have been adjusted by the programmer to point to the correct address.

see sigaltstack Incompatibility for further details.

No Lex, Yacc Libraries

The lex library, libl, is not supplied in an ABI version. Programs cannot be linked with the -ll option. Similarly, the yacc library liby, is not supplied so programs cannot be linked with -ly. These libraries can be obtained from MIPS ABI Developer Support if needed.

strtod Errors

C library routines which make use of the internal routine _tenscale suffer from an implementation problem on IRIX which may give bad results. The affected routines are strtod, atof, ecvt and fcvt, and possibly also the floating point portions of the printf family. This has been corrected in IRIX 5.3 Reference Platform.

FD_ZERO Macro in <sys/select.h> Not ABI-Clean

The FD_ZERO macro in system header file <sys/select.h> contains a reference to the bzero routine, which is not part of the MIPS ABI. This can be worked around by defining bzero in the program in terms of the memset routine:

     #define bzero(s, n) memset((s), 0, (n))

An alternative is to modify the include file to redefine the FD_ZERO macro, although changing a system include file usually is undesirable. To make the modification, the define should be changed to look like this:

     #ifdef _ABI_SOURCE
     #define FD_ZERO(p)      memset((char *)(p), 0, sizeof(*(p)))
     #else
     #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
     #endif

This has been corrected in the IRIX 5.3 Reference Platform.

Output Buffers Not Flushing

The standard library routine _cleanup performs flush-on-exit processing for standard I/O. This routine is intended to be called automatically when a program exits normally (it is not called if _exit is called or the program terminates abnormally). On many of the MIPS ABI systems, the call is arranged for by having the run-time startup prologue, crt1.o, register a call to _cleanup with the atexit routine. On IRIX, the call is arranged by having the C library exit routine make the call. When a program is made using the Reference Platform scheme, it will be bound with the IRIX crt1.o, which does not contain the atexit registration, and when that program is run on a different ABI platform, which does not contain the call to _cleanup from exit, the effect is that _cleanup is not called.

How the call is _cleanup is to be arranged is not specified by the MIPS ABI. The member companies have agreed to change their methods to be compatible with code built on the Reference Platform. However, in the interim, a workaround is needed. The simplest workaround is to simply insert the equivalent to what the native crt1.o would have done very early in the program - somewhere at the top of the main routine seems best:

     atexit(_cleanup);
The MIPS ABI Developer Support program or the individual platform vendors can supply information about which operating system revisions need the workaround, or, optionally, the application may choose to simply use the workaround regardless of target.

Divide-by-Zero Gives SIGTRAP

An integer divide-by-zero will raise a SIGTRAP signal on IRIX 5.2. The ABI requires the behavior specified in the SVID, which is to raise a SIGFPE signal and set the siginfo indication (SI_CODE) to FPE_INTDIV. There is no current workaround. This has been correct in the IRIX 5.3 Reference Platform.

tanh Errors

The tanh routine in the Math library (libm) will overflow on large numbers (numbers which are more than half the MAX_DOUBLE value) on IRIX 5.2. There is no current workaround. This has been correct in the IRIX 5.3 Reference Platform.

abicc Doesn't Pass Some Linker Flags

The abicc shell script does not pass through some linker flags that it ought to. Neither -Wl,xxx construct nor the specific flag will be passed unless it is among those documented in the MIPS ABI Conformance Guide 1.1 documented for the abicc command. For example, the -znodefs option is needed on some platforms because of other bugs, but it cannot be supplied from the abicc command line. There are two possible workarounds.

One approach is to modify the setup script for abicc. A possible way to do this would be to change the options line in the setup script (/usr/lib/abi/sgicc.cfg on IRIX) to pass a variable, the required flags can then be passed via an environment variable. For example, if the line looked like this:

     options="-abi"
it could be changed to
     options="-abi $ABICC_EXTRA"
and then a flag could be passed by doing (for csh users):
     setenv ABICC_EXTRA -znodefs

Another possible approach is to use abild to do linking. `abild' will accept all the options documented for it, so there is no problem with whether abicc will pass them on correctly. However, linking with abild is trickier than linking with abicc since the right startup files and default libraries must be supplied. Linking with abild has the same relationship to abicc as linking with ld has to cc; if you would normally link with ld it makes sense to use abild, otherwise it probably doesn't. To get a start on linking with abild, use abicc once to link the program, specifying the -v flag, save the output, and use it to begin building up a correct link line for abild.

This has been corrected in IRIX 5.3 and the above approach is not recommended.

Writable Strings

Some platforms are more restrictive that others in their default linking behavior. One such problem area is with the placement of "string" data. With ANSI C, such data is usually made to be const, meaning it will be read-only. However, older code may still depend on being able to modify locations in a string, for example, in the case where a *template* string is used to generate a temporary name. While this is bad coding practice by current standards, there is a recognition that legacy code may depend on this behavior. On IRIX, the default behavior is to put string and other constant data into a special rodata section, but to place that section within the data section, where it remains writable. Other platforms will make it read-only.

This becomes an issue where a program is linked and tested on the Reference Platform, where an code which modifies a string in this manner would still work; then is relinked on one of the more restrictive platforms which will put the string into read-only memory and potentially fail the program. It is only an issue where strings are actually written to. This is only for cases where the string would appear constant, like this example:

     char string[] = "templateXXXX";
and something knows to start writing a pattern beginning at string[8].

One workaround is to inform the IRIX linker to put the strings into read-only memory, such that errors of this type will be noticed during the testing phase. This option cannot be supplied using abicc at the moment; the -rdata_shared flag needs to be given to the linker. One possible approach is to use the technique for modifying the configuration script for abicc as noted in abicc Doesn't Pass Some Linker Flags, then define ABICC_EXTRA like this (for csh users):

     setenv ABICC_EXTRA "-Wl,-rdata_shared".
This is correct only for IRIX and other platforms whose native linker accept the -rdata_shared flag.

An abicc flag to acces the -rdata_shared behavior will be available in the next release.

IRIX 5.3 known issues and problems

Network Header Define Inconsistency

There is an inconsistency in the values given to some variables in some of the networking header files. The following table presents the values that are expected by the current Conformance Guide and actual values on the vendor platforms:
Legend
        BB      Black Book
        CCUR    Concurrent
        CDS     Control Data
        NEC     NEC
        PYRAMID Pyramid
        SGI     IRIX 5.3 Reference Platform
        SNI     Siemens Nixdorf
        SONY    Sony
        TANDEM  Tandem

        def means that there is a definition for the call
        def! indicates that there is no definition for the define or call

                     BB  CCUR   CDS   NEC PYRAMID  SGI   SNI  SONY TANDEM 
netinet/in.h
  htonl             def   def   def   def    def   def   def   def   def! 
  htons             def   def   def   def    def   def   def   def   def! 
  ntohl             def   def   def   def    def   def   def   def   def! 
  ntohs             def   def   def   def    def   def   def   def   def! 

netinet/in.h
  IP_ADD_MEMBERSHIP  5   def!     5     5   def!    23  def!     5      5 
  IP_DROP_MEMBERSHIP 6   def!     6     6   def!    24  def!     6      6 
  IP_HDRINCL         7   def!     7     7   def!     2  def!     7   def! 
  IP_MULTICAST_IF    2   def!     2     2   def!    20  def!     2      3 
  IP_MULTICAST_LOOP  4   def!     4     4   def!    22  def!     4      4 
  IP_MULTICAST_TTL   3   def!     3     3   def!    21  def!     3      2 
  IP_RECVDSTADDR    12   def!    12    12   def!     7  def!    12   def! 
  IP_RECVOPTS       10   def!    10    10   def!     5  def!    10   def! 
  IP_RECVRETOPTS    11   def!    11    11   def!     6  def!    11   def! 
  IP_RETOPTS        13   def!    13    13   def!     8  def!    13   def! 
  IP_TOS             8      2     8     8   def!     3     2     8      7 
  IP_TTL             9   def!     9  def!   def!     4     3     9      2 

net/if.h
  IFF_MULTICAST  0x800   def!  def! 0x800   def! 0x800  def! 0x800 0x4000 

net/route.h
  RTF_REINSTATE    0x8    0x8   0x8   0x8    0x8   0x8   0x8  def!    0x8 

sys/socket.h
  AF_NBS             7      7     7     7      7  def!     7     7      7 
  AF_OSINET         21     21    21    21      2    21     2    21     21 
  AF_X25            20     20  def!    20     20    20    20    20     20 
  PF_NBS             7      7     7     7      7  def!     7     7      7 
  PF_X25            20     20  def!    20     20    20    20    20     20 

Values that are not defined are not necessarily in error as the Conformance Guide does not mandate the presence of the variables. It is advised that those variables that have conflicting definitions are not used as behavior will not be consistent.

Syslog Inconsistency

The syslog(3) behaves inconsistently on some platforms. On the current Reference Platform, /dev/log is used as the device through which the syslog call outputs to the console. It is known that on some platforms different devices are used. The following table shows the platforms and the device nodes that are used for syslog output.

The following table represents the devices that are used when an application uses syslog natively:

	NEC     	/dev/conslog
	Sony    	/dev/log
	Control Data	/dev/log
	Concurrent	/dev/conslog
	Dansk Data	/dev/conslog
	SNI		/dev/conslog
	Pyramid		/dev/conslog
	SGI     	/dev/log
	Tandem		/dev/eventwrite
The current workaround is to ensure that there is a /dev/log present for and that it matches the major and minor numbers for the designated file in /dev.

Back to the MIPS ABI Home Page


Maintained by webmaster@mipsabi.org
last modified on 96/02/23

Copyright © 1995, MIPS ABI Group, Incorporated.